#include <stdlib.h>
#include "Arbre.h"
#include "Symbole.h"
#include "SymboleValue.h"
#include "Valeur.h"
#include "MotsCles.h"
#include <typeinfo>


////////////////////////////////////////////////////////////////////////////////
SymboleValue::SymboleValue(Symbole s, string type, unsigned int ligne) :
        Symbole(s.getChaine()) {
    if (s == "<ENTIER>") {
        valeur = new ValeurInt(atoi(s.getChaine().c_str()));
        defini = true;
        this->type = ENTIER;
    }
    else if (s == "<REEL>") {
        valeur = new ValeurFloat(atof(s.getChaine().c_str()));
        defini = true;
        this->type = REEL;
    }
    else if (s == "<CHAINE>") {
      string ch = "";
      for (unsigned int i = 1; i <= s.getChaine().size()-2; i++)
	  ch += s.getChaine()[i];
        valeur = new ValeurString(ch);
        defini = true;
        this->type = CHAINE;
    }
    else if (s == "<CARACT>") {
        valeur = new ValeurChar(s.getChaine()[1]);
        defini = true;
        this->type = CHAR;
    }
    else {
        if (type==ENTIER) {
            valeur = new ValeurInt(0);
            this->type = ENTIER;
        }
        if (type==REEL) {
            valeur = new ValeurFloat(0.0);
            this->type = REEL;
        }
        if (type==CHAINE) {
            valeur = new ValeurString("\0");
            this->type = CHAINE;
        }
        if (type==CHAR) {
            valeur = new ValeurChar('\0');
            this->type = CHAR;
        }
        defini = false;
    }
    this->ligne=ligne;
}


////////////////////////////////////////////////////////////////////////////////
// Attention : cette fonction (operator) n'est pas membre de la classe SymboleValue
ostream & operator <<(ostream & cout, SymboleValue symb) {
    cout << (Symbole) symb << "\t\t -, " << symb.getType() << " (ligne " << symb.getLigne() <<") Valeur=";
    Valeur* val = symb.valeur;
    if (symb.defini) {
        if (typeid(*val) == typeid(ValeurInt))
            cout << ((ValeurInt*)val)->getValeur() << " ";
        else if (typeid(*val) == typeid(ValeurFloat))
            cout << ((ValeurFloat*)val)->getValeur() << " ";
        else if (typeid(*val) == typeid(ValeurString))
            cout << ((ValeurString*)val)->getValeur() << " ";
           else if (typeid(*val) == typeid(ValeurChar))
	    cout << ((ValeurChar*)val)->getValeur() << " ";
    }
    else
        cout << "indefinie ";
    return cout;
}

Valeur*  SymboleValue::getValeur() {
    return this->valeur;                        // accesseur
}

void SymboleValue::setValeur(Valeur* valeur)    {
    this->valeur=valeur;    // accesseur
    defini=true;
}


void SymboleValue::Accept(NoeudVisitor& visitor) {
    if (typeid(visitor) == typeid(AfficherVisitor)) {
        visitor.IncresIndentation();
        visitor.VisitSymboleValue(this);
        visitor.DecresIndentation();
    }
    else {
        visitor.VisitSymboleValue(this);
    }
}
